class WaterfallContent {
  constructor(config = {}) {
    this.init(config);
  }
  init(config = {}) {
    this.imgList = config.imgList || [];
    this.column = config.column || 8;
    this.imgMargin = config.imgMargin || 0.5;
    this.domId = config.domId || "waterfall-container";
    this.minHeight = [];
    this.arr = [];
    const ul = document.getElementById(this.domId);
    ul.innerHTML = "";
  }
  async create(imgList = this.imgList, cb) {
    this.init();
    this.imgList = imgList;
    const ul = document.getElementById(this.domId);
    ul.innerHTML = "";
    let trueWidth = Math.floor(
      (100 - this.column * this.imgMargin * 2) / this.column
    );
    let trueWidthPx = 0;
    for (let i = 0; i < this.column; i++) {
      let li = document.createElement("li");
      li.style.listStyle = "none";
      li.style.float = "left";
      li.style.width = `${trueWidth}%`;
      li.style.margin = `0 ${this.imgMargin}%`;
      li.classList.add("git-img");

      ul.appendChild(li);
      this.arr.push(li);
      this.minHeight.push(0);
      trueWidthPx = li.offsetWidth;
    }
    this.loadHandler(trueWidthPx, cb);
  }
  getBase64(file) {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    return new Promise((resolve) => {
      reader.onload = () => {
        resolve(reader.result);
      };
    });
  }
  getImgPx(img, maxWidth) {
    const image = new Image();
    image.src = img;
    return new Promise((resolve) => {
      image.onload = () => {
        const width = image.width;
        const height = image.height;
        image.width = maxWidth;
        image.height = image.height * (maxWidth / width);
        resolve({ width, height, image });
      };
    });
  }
  async loadHandler(trueWidth, cb) {
    for (let i = 0; i < this.imgList.length; i++) {
      const imgItem = this.imgList[i];
      const src = imgItem.download_url;
      const res = await this.getImgPx(src, trueWidth);
      const { image } = res;
      const minHeight = this.minHeight;
      const arr = this.arr;
      // 高度数组的最小值
      const min = Math.min.apply(null, minHeight);
      // 高度数组的最小值索引
      const minIndex = minHeight.indexOf(min);
      // 克隆一份图片
      const im = image.cloneNode(true);
      im.setAttribute("data-sha", imgItem.sha);
      im.onclick = this.imgClick;
      // 将图片假如对应最小值索引的容器中
      arr[minIndex].appendChild(im);
      // 更新最小值索引的容器的高度
      minHeight[minIndex] += im.height;
      if (i === 0 && cb) {
        cb();
      }
    }
  }
}
